home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / PNL Libraries / Libraries / Mercutio API.p
Text File  |  1994-09-23  |  13KB  |  391 lines

  1. UNIT MercutioAPI;
  2.  
  3.     {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  4.     {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  5.     {xxx}
  6.     {xxx                  Developer's Programming Interface for Mercutio MDEFs}
  7.     {xxx                        ©1992-1994 Ramon M. Felciano, All Rights Reserved}
  8.     {xxx}
  9.     {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  10.     {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  11.  
  12. INTERFACE
  13.  
  14.     CONST
  15.  
  16.         customDefProcSig = 'CUST';
  17.         areYouCustomMsg = ord('*') * 256 + ord('*');
  18.         getVersionMsg = ord('*') * 256 + ord('v');
  19.         getCopyrightMsg = ord('*') * 256 + ord('©');
  20.         setCallbackMsg = ord('*') * 256 + ord('c');
  21.         stripCustomDataMsg = ord('*') * 256 + ord('d');
  22.         setPrefsMsg = ord('*') * 256 + ord('p');
  23.  
  24.         mMenuKeyMsg = ord('S') * 256 + ord('K');        {see if key press is key-equiv for this menu}
  25.         mDrawItemStateMsg = ord('S') * 256 + ord('D');        { draw the specified item in the specifed box }
  26.         mCountItemsMsg = ord('S') * 256 + ord('C');    { return count of items in menu }
  27.  
  28.         cbBasicDataOnlyMsg = 1;
  29.         cbIconOnlyMsg = 2;
  30.     TYPE
  31.         MenuPrefsPtr = ^MenuPrefsRec;
  32.         MenuPrefsRec = RECORD
  33.                 isDynamicFlag, forceNewGroupFlag, useCallbackFlag, controlKeyFlag, optionKeyFlag, shiftKeyFlag, cmdKeyFlag: style;
  34.                 requiredModifiers: integer;
  35.             END;
  36.  
  37.         MenuResPrefsHandle = ^MenuResPrefsPtr;
  38.         MenuResPrefsPtr = ^MenuResPrefs;
  39.         MenuResPrefs = RECORD
  40.                 version: integer;
  41.                 thePrefs: MenuPrefsRec;
  42.             END;
  43.  
  44.     {ItemFlagsRec: additional fields supported by Mercutio MDEFs}
  45.         ItemFlagsPtr = ^ItemFlagsRec;
  46.         ItemFlagsRec = PACKED RECORD
  47.             { high byte }
  48.                 forceNewGroup: boolean;
  49.                 isDynamic: boolean;
  50.                 useCallback: boolean;
  51.                 controlKey: boolean;
  52.                 optionKey: boolean;
  53.                 unused10: boolean;
  54.                 shiftKey: boolean;
  55.                 cmdKey: boolean;
  56.  
  57.             { low byte }
  58.                 isHier: boolean;
  59.                 changedByCallback: boolean;
  60.                 Enabled: boolean;
  61.                 hilited: boolean;
  62.                 smallIcon: boolean;
  63.                 hasIcon: boolean;
  64.                 unused1, unused0: boolean;
  65.             END;
  66.  
  67.     {StdItemData: record structure from the standard menu item structure}
  68.         richItemData = PACKED RECORD
  69.                 iconID: Byte;        { resource ID of the icon to display (0 if none) }
  70.                 keyEq: char;        { keyboard equivalent (or special control value) }
  71.                 mark: char;        { mark character, (chr(0) if none) }
  72.                 textStyle: Style;    { text style of the item }
  73.                 itemID: integer;    { index position within the menu }
  74.                 itemRect: rect;        { where the item will be drawn }
  75.                 flags: itemFlagsRec;    { special Mercutio flags }
  76.                 iconType: ResType;    { resource type of the icon (used for disposing of icon data)}
  77.                 hIcon: Handle;        { handle to the icon data }
  78.                 pString: stringPtr;    { points to itemStr, or to string in menuHandle }
  79.                 itemStr: str255;    { used for callback string passing }
  80.                 cbMsg: integer;        { callback message }
  81.             END;
  82.         richItemPtr = ^richItemData;
  83.  
  84. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  85. {x}
  86. {x    MDEF_MenuKey is a replacement for the standard toolbox call MenuKey for use with the}
  87. {x    Mercutio MDEF. Given the keypress message and modifiers parameters from a standard event, it }
  88. {x    checks to see if the keypress is a key-equivalent for a particular menuitem. If you are currently}
  89. {x    using custom menus (i.e. menus using a Mercutio MDEF), pass the handle to one of these menus in}
  90. {x    hMenu. If you are not using custom menus, pass in NIL or another menu, and MDEF_MenuKey will use the}
  91. {x    standard MenuKey function to interpret the keypress.}
  92. {x}
  93. {x    As with MenuKey, MDEF_MenuKey returns the menu ID in high word of the result, and the menu}
  94. {x    item in the low word.}
  95. {x}
  96. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  97.  
  98.     FUNCTION MDEF_MenuKey (theMessage: longint; theModifiers: integer; hMenu: menuHandle): longint;
  99.  
  100.  
  101. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  102. {x}
  103. {x    These routines allow you to retrieve the Copyright and Version information}
  104. {x    embedded within the MDEF. The Version information is returned as a longint,}
  105. {x    which can be typecast to a normal version resource.}
  106. {x}
  107. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  108.  
  109.     FUNCTION MDEF_GetCopyright (menu: MenuHandle): str255;
  110.     FUNCTION MDEF_GetVersion (menu: MenuHandle): longint;
  111.  
  112.  
  113. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  114. {x}
  115. {x    MDEF_CalcItemSize will calculate the height and width for a given menu item. It assumes the top and}
  116. {x    left fields of theRect are filled in; the MDEF will fill in the bottom and right.}
  117. {x}
  118. {x    MDEF_DrawItem will draw a given item in the rectangle you specify. You can indicate whether the}
  119. {x    the item should be hilited or enabled.}
  120. {x}
  121. {x    MDEF_DrawItemState is similar but allows you to draw the item disabled or hilited.}
  122. {x}
  123. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  124.  
  125.     PROCEDURE MDEF_CalcItemSize (menu: MenuHandle; item: integer; VAR theRect: rect);
  126.     PROCEDURE MDEF_DrawItem (menu: MenuHandle; item: integer; destRect: rect);
  127.     PROCEDURE MDEF_DrawItemState (menu: MenuHandle; item: integer; destRect: rect; hilited, enabled: boolean);
  128.  
  129. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  130. {x}
  131. {x    MDEF_StripCustomMenuData will remove any custom data allocated by the Mercutio MDEFs. Use this}
  132. {x    before writing a MENU resource to disk (esp. if you are using callbacks)}
  133. {x}
  134. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  135.     PROCEDURE MDEF_StripCustomMenuData (menu: MenuHandle);
  136.  
  137.  
  138.  
  139. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  140. {x}
  141. {x    MDEF_SetCallbackProc sets the procedure that will be called for each item before it is drawn. The}
  142. {x    procedure is also called during the SizeMenu message call.}
  143. {x}
  144. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  145.     PROCEDURE MDEF_SetCallbackProc (menu: MenuHandle; theProc: procPtr);
  146.  
  147.  
  148. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  149. {x}
  150. {x    MDEF_SetMenuPrefs lets you determine which style bits for the menuItems will be interepreted}
  151. {x    as feature flags for the MDEF.}
  152. {x}
  153. {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  154.     PROCEDURE MDEF_SetMenuPrefs (menu: MenuHandle; pPrefs: MenuPrefsPtr);
  155.  
  156.  
  157.  
  158. IMPLEMENTATION
  159.  
  160.     PROCEDURE CallMDEF (message: integer; theMenu: MenuHandle; VAR menuRect: Rect; hitPt: Point; VAR whichItem: integer; defProc: ProcPtr);
  161.     {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  162.     {x    Simple inline assembly code to call an MDEF, courtesy of John Cavallino. }
  163.     {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  164.     INLINE
  165.         $205F,    { move.l (SP)+,A0 }
  166.         $4E90;    { jsr (A0) }
  167.  
  168.  
  169.     PROCEDURE MDEF_SetMenuPrefs (menu: MenuHandle; pPrefs: MenuPrefsPtr);
  170.         VAR
  171.             state: SignedByte;
  172.             proc: handle;
  173.             dummyRect: rect;
  174.             dummyInt: integer;
  175.     BEGIN
  176.         proc := menu^^.menuProc;
  177.         state := HGetState(proc);
  178.         HLock(proc);
  179.         dummyInt := 0;
  180.         dummyRect.topLeft := point(longint(0));
  181.         dummyRect.botRight := point(longint(0));
  182.         CallMDEF(setPrefsMsg, menu, dummyRect, point(pPrefs), dummyInt, proc^);
  183.         HSetState(proc, state);
  184.         CalcMenuSize(menu);    { size may have changed based on new Prefs }
  185.     END;
  186.  
  187.  
  188.  
  189.     PROCEDURE MDEF_SetCallbackProc (menu: MenuHandle; theProc: procPtr);
  190.         VAR
  191.             state: SignedByte;
  192.             proc: handle;
  193.             dummyRect: rect;
  194.             dummyInt: integer;
  195.     BEGIN
  196.         proc := menu^^.menuProc;
  197.         state := HGetState(proc);
  198.         HLock(proc);
  199.         dummyInt := 0;
  200.         dummyRect.topLeft := point(longint(0));
  201.         dummyRect.botRight := point(longint(0));
  202.         CallMDEF(setCallbackMsg, menu, dummyRect, point(theProc), dummyInt, proc^);
  203.         HSetState(proc, state);
  204.     END;
  205.  
  206.  
  207.  
  208.     PROCEDURE MDEF_StripCustomMenuData (menu: MenuHandle);
  209.         VAR
  210.             state: SignedByte;
  211.             proc: handle;
  212.             dummyPoint: point;
  213.             dummyItem: integer;
  214.             dummyRect: rect;
  215.     BEGIN
  216.         proc := menu^^.menuProc;
  217.         state := HGetState(proc);
  218.         HLock(proc);
  219.         CallMDEF(stripCustomDataMsg, menu, dummyRect, dummyPoint, dummyItem, proc^);
  220.         HSetState(proc, state);
  221.     END;
  222.  
  223.  
  224.  
  225.     PROCEDURE MDEF_DrawItem (menu: MenuHandle; item: integer; destRect: rect);
  226.         VAR
  227.             state: SignedByte;
  228.             proc: handle;
  229.             dummyPt: point;
  230.     BEGIN
  231.         proc := menu^^.menuProc;
  232.         state := HGetState(proc);
  233.         HLock(proc);
  234.         CallMDEF(mDrawItemMsg, menu, destRect, dummyPt, item, proc^);
  235.         HSetState(proc, state);
  236.     END;
  237.  
  238.  
  239.  
  240.     PROCEDURE MDEF_DrawItemState (menu: MenuHandle; item: integer; destRect: rect; hilited, enabled: boolean);
  241.         VAR
  242.             state: SignedByte;
  243.             proc: handle;
  244.             dummyPt: point;
  245.     BEGIN
  246.         proc := menu^^.menuProc;
  247.         state := HGetState(proc);
  248.         HLock(proc);
  249.         dummyPt.h := byte(hilited);
  250.         dummyPt.v := byte(enabled);
  251.         CallMDEF(mDrawItemStateMsg, menu, destRect, dummyPt, item, proc^);
  252.         HSetState(proc, state);
  253.     END;
  254.  
  255.  
  256.  
  257.     PROCEDURE MDEF_CalcItemSize (menu: MenuHandle; item: integer; VAR theRect: rect);
  258.         VAR
  259.             state: SignedByte;
  260.             proc: handle;
  261.             dummyPt: point;
  262.     BEGIN
  263.         proc := menu^^.menuProc;
  264.         state := HGetState(proc);
  265.         HLock(proc);
  266.         CallMDEF(mCalcItemMsg, menu, theRect, dummyPt, item, proc^);
  267.         HSetState(proc, state);
  268.     END;
  269.  
  270.  
  271.  
  272.     FUNCTION MDEF_IsCustom (menu: MenuHandle): boolean;
  273.     {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  274.     {x}
  275.     {x    MDEF_IsCustom returns true if hMenu is controlled by a custom MDEF. This relies on my}
  276.     {x    convention of returning the customDefProcSig constant in the rect parameter: this obtuse}
  277.     {x    convention should be unique enough that only my custom MDEFs behave this way.}
  278.     {x}
  279.     {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
  280.         VAR
  281.             state: SignedByte;
  282.             proc: handle;
  283.             dummy: rect;
  284.             dummyInt: integer;
  285.             hRes: handle;
  286.     BEGIN
  287.         proc := menu^^.menuProc;
  288.         hRes := GetResource('MDEF', 0);
  289.         IF hRes^ = proc^ THEN
  290.             MDEF_IsCustom := false
  291.         ELSE BEGIN
  292.                 state := HGetState(proc);
  293.                 HLock(proc);
  294.                 dummy.topLeft := point(longint(0));
  295.                 CallMDEF(areYouCustomMsg, menu, dummy, point(longint(0)), dummyInt, proc^);
  296.                 HSetState(proc, state);
  297.                 MDEF_IsCustom := longint(dummy.topLeft) = longint(customDefProcSig);
  298.             END;
  299.     END;
  300.  
  301.  
  302.     FUNCTION MDEF_GetVersion (menu: MenuHandle): longint;
  303.         VAR
  304.             state: SignedByte;
  305.             proc: handle;
  306.             dummy: rect;
  307.             dummyInt: integer;
  308.     BEGIN
  309.         proc := menu^^.menuProc;
  310.         state := HGetState(proc);
  311.         HLock(proc);
  312.         dummy.topLeft := point(longint(0));
  313.         CallMDEF(getVersionMsg, menu, dummy, point(longint(0)), dummyInt, proc^);
  314.         HSetState(proc, state);
  315.         MDEF_GetVersion := longint(dummy.topLeft);
  316.     END;
  317.  
  318.     FUNCTION MDEF_GetCopyright (menu: MenuHandle): str255;
  319.         VAR
  320.             state: SignedByte;
  321.             proc: handle;
  322.             dummy: rect;
  323.             dummyInt: integer;
  324.             hCopyright: stringHandle;
  325.     BEGIN
  326.         MDEF_GetCopyright := '';
  327.         proc := menu^^.menuProc;
  328.         state := HGetState(proc);
  329.         HLock(proc);
  330.         dummy.topLeft := point(longint(0));
  331.         CallMDEF(getCopyrightMsg, menu, dummy, point(longint(0)), dummyInt, proc^);
  332.         HSetState(proc, state);
  333.         hCopyright := stringHandle(dummy.topLeft);
  334.         IF hCopyright <> NIL THEN
  335.             MDEF_GetCopyright := hCopyright^^;
  336.         disposeHandle(handle(hCopyright));
  337.     END;
  338.  
  339.  
  340.  
  341.     FUNCTION MDEF_MenuKey (theMessage: longint; theModifiers: integer; hMenu: menuHandle): longint;
  342.         VAR
  343.             state: SignedByte;
  344.             proc: handle;
  345.             dummyRect: rect;
  346.             dummyInt: integer;
  347.     BEGIN
  348.         IF ((hMenu = NIL) | (NOT MDEF_IsCustom(hMenu))) THEN
  349.             MDEF_MenuKey := MenuKey(char(bitAnd(theMessage, charcodemask)))
  350.         ELSE BEGIN
  351.                 proc := hMenu^^.menuProc;
  352.                 state := HGetState(proc);
  353.                 HLock(proc);
  354.                 dummyRect.topLeft := point(longint(0));
  355.                 CallMDEF(mMenuKeyMsg, hMenu, dummyRect, point(theMessage), themodifiers, proc^);
  356.                 HSetState(proc, state);
  357.                 MDEF_MenuKey := longint(dummyRect.topleft);
  358.             END;
  359.     END;
  360.  
  361.  
  362. { VERSION HISTORY }
  363. {}
  364. { Version 1.2b16}
  365. { ===========}
  366. { - fixed color menu bug (drew background in white)}
  367. { - change callback procedure to accept a parameter block with cbMsg message}
  368. { - callback called twice: once for item data, once for icon data}
  369. { - renamed API for consistency (all routines start with MDEF_ )}
  370. { - PowerMenuKey renamed MDEF_MenuKey}
  371. {}
  372.  
  373. { Version 1.2b12}
  374. { ============ }
  375. { - integrated all MDEFs back into Mercutio}
  376. { - introduced Menu preferences for setting style bit mapping and required modifier keys}
  377. { - new 'dirty' parameter to Callback avoids unnecessary flicker }
  378. { - modifer parameter in Callback changed to Status to allow information to persist across calls }
  379. {}
  380. {}
  381.  
  382.  
  383.  
  384. {11/13/92    1.1.1    Fixed keyTrans bug (w. Dvorak keyboard)}
  385. {1.1.2    Built C API, works with on-the-fly menus}
  386. {1.1.3    Added Copyright support}
  387. {1.1.4    Fixed popup bug, works with Greg's buttons}
  388. {1.1.5    Fixed bug with 'empty' mctbs; removed debugging code (alternate way to show disabled modifiers)}
  389. {2/21/93    1.2    Added icon suite support; renumbered MDEF font to resolve conflict with Geneva}
  390.  
  391. END.